package com.sukaiyi.giteeideaplugin.mainwindow;

import cn.hutool.core.swing.ClipboardUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.intellij.icons.AllIcons;
import com.intellij.ide.impl.ProjectUtil;
import com.intellij.ide.plugins.newui.ColorButton;
import com.intellij.ide.ui.ProductIcons;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBRadioButton;
import com.intellij.util.IconUtil;
import com.intellij.util.ui.AnimatedIcon;
import com.sukaiyi.giteeideaplugin.externcmd.CommandExecutor;
import com.sukaiyi.giteeideaplugin.externcmd.GitCommandExecutor;
import com.sukaiyi.giteeideaplugin.setting.PluginSetting;
import com.sukaiyi.giteeideaplugin.utils.IdeaUIUtils;
import com.sukaiyi.giteeideaplugin.utils.ProjectUtils;
import icons.PluginIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.io.File;
import java.io.IOException;
import java.util.Objects;

public class CloneRepoWindow extends DialogWrapper {

    private final PluginSetting pluginSetting = PluginSetting.getInstance();

    private final JSONObject repo;

    private JPanel content;
    private JBLabel repoNameLabel;
    private JButton intellijIDEAButton;
    private JButton webStormButton;
    private JButton fileExplorerButton;
    private TextFieldWithBrowseButton clonePathField;
    private com.intellij.ui.components.JBTextArea processOutputArea;
    private AnimatedIcon animatedIcon;
    private ColorButton cloneButton;
    private JBRadioButton sshRadioButton;
    private JBRadioButton httpsRadioButton;
    private JBLabel urlLabel;
    private JPanel urlLabelParentPanel;


    public CloneRepoWindow(JSONObject repo) {
        super(true);
        setTitle(repo.getStr("name"));
        init();
        this.repo = repo;
        repoNameLabel.setIcon(PluginIcons.REPO_BLUE);
//        intellijIDEAButton.setIcon(IconUtil.scaleByFont(PluginIcons.IDE_IDEA, null, 3.5f));
        intellijIDEAButton.setIcon(ProductIcons.getInstance().getProductIcon());
        intellijIDEAButton.addActionListener(this::onCloneAndOpenWithThisIde);
        webStormButton.setIcon(IconUtil.scaleByFont(PluginIcons.IDE_WS, null, 3.5f));
        webStormButton.addActionListener(this::onCloneAndOpenWithThisIde);
        fileExplorerButton.setIcon(AllIcons.General.OpenDisk);
        fileExplorerButton.addActionListener(this::onCloneAndOpenWithFileExplorer);
        clonePathField.addBrowseFolderListener("Clone Path", null, ProjectUtils.getProject(), FileChooserDescriptorFactory.createSingleFolderDescriptor());
        clonePathField.setText(pluginSetting.getDefaultClonePath());
        if (Objects.equals(pluginSetting.getDefaultProtocol(), "https")) {
            httpsRadioButton.setSelected(true);
            urlLabel.setText(repo.getStr("html_url"));
        } else {
            sshRadioButton.setSelected(true);
            urlLabel.setText(repo.getStr("ssh_url"));
        }
        urlLabel.setCopyable(true);
        httpsRadioButton.addItemListener(this::onHttpsRadioButtonChange);
        sshRadioButton.addItemListener(this::onSSHRadioButtonChange);
        cloneButton.addActionListener(this::onCloneButton);

        DefaultActionGroup actionGroup = new DefaultActionGroup();
        actionGroup.add(new AnAction(AllIcons.General.CopyHovered) {
            @Override
            public void actionPerformed(@NotNull AnActionEvent event) {
                String content = urlLabel.getText();
                ClipboardUtil.setStr(content);
            }
        });
        ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar("Group Toolbar", actionGroup, true);
        urlLabelParentPanel.add(actionToolbar.getComponent());
    }

    public void onHttpsRadioButtonChange(ItemEvent event) {
        if (event.getStateChange() == ItemEvent.SELECTED) {
            urlLabel.setText(repo.getStr("html_url"));
        }
    }

    public void onSSHRadioButtonChange(ItemEvent event) {
        if (event.getStateChange() == ItemEvent.SELECTED) {
            urlLabel.setText(repo.getStr("ssh_url"));
        }
    }

    public void onCloneAndOpenWithThisIde(ActionEvent event) {
        String url = repo.getStr("ssh_url");
        String dist = clonePathField.getText();
        int lastIndex = url.lastIndexOf('/');
        String projectName = StrUtil.removeSuffix(url.substring(lastIndex + 1), ".git");
        clone(url, dist, new CommandExecuteAdapter() {
            @Override
            public void onFinish(int exitCode) {
                if (exitCode == 0) {
                    SwingUtilities.invokeLater(() -> {
                        String path = dist + File.separator + projectName;
                        ProjectUtil.openOrImport(path, null, true);
                    });
                }
            }
        });
    }

    public void onCloneAndOpenWithFileExplorer(ActionEvent event) {
        String url = repo.getStr("ssh_url");
        String dist = clonePathField.getText();
        int lastIndex = url.lastIndexOf('/');
        String projectName = StrUtil.removeSuffix(url.substring(lastIndex + 1), ".git");
        clone(url, dist, new CommandExecuteAdapter() {
            @Override
            public void onFinish(int exitCode) {
                super.onFinish(exitCode);
                if (exitCode == 0) {
                    Desktop desktop = Desktop.getDesktop();
                    try {
                        desktop.open(new File(dist + File.separator + projectName));
                    } catch (IllegalArgumentException | IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    public void onCloneButton(ActionEvent event) {
        String url = repo.getStr("ssh_url");
        String dist = clonePathField.getText();
        clone(url, dist, null);
    }

    private void clone(String url, String dist, CommandExecutor.CommandExecuteListener listener) {
        animatedIcon.resume();
        animatedIcon.setVisible(true);
        processOutputArea.append("Start Clone...\n");

        GitCommandExecutor gitCommandExecutor = GitCommandExecutor.builder()
                .gitExecutablePath(pluginSetting.getGitExecutablePath())
                .build();
        CommandExecutor.CommandExecuteListener baseListener = new CommandExecutor.CommandExecuteListener() {
            @Override
            public void onLine(String line) {
                SwingUtilities.invokeLater(() -> processOutputArea.append(line + "\n"));
                if (listener != null) {
                    listener.onLine(line);
                }
            }

            @Override
            public void onFinish(int exitCode) {
                SwingUtilities.invokeLater(() -> {
                    animatedIcon.suspend();
                    animatedIcon.setVisible(false);
                    processOutputArea.append("process exited with code:" + exitCode + "\n");
                    if (exitCode == 0) {
                        SwingUtilities.invokeLater(() -> CloneRepoWindow.this.close(0, true));
                    }
                });
                if (listener != null) {
                    listener.onFinish(exitCode);
                }
            }

            @Override
            public void onException(Throwable e) {
                SwingUtilities.invokeLater(() -> {
                    animatedIcon.suspend();
                    animatedIcon.setVisible(false);
                    processOutputArea.append("exec failed: " + e.getMessage() + "\n");
                });
                if (listener != null) {
                    listener.onException(e);
                }
            }
        };
        gitCommandExecutor.cloneAsync(url, dist, baseListener);
    }

    public void createUIComponents() {
        animatedIcon = IdeaUIUtils.createBigProgressIcon();
        animatedIcon.suspend();
        animatedIcon.setVisible(false);
    }

    @Nullable
    @Override
    protected JComponent createCenterPanel() {
        return content;
    }

    @Nullable
    @Override
    protected String getDimensionServiceKey() {
        return this.getClass().getName();
    }

    @NotNull
    @Override
    protected Action[] createActions() {
        return new Action[0];
    }

    private static class CommandExecuteAdapter implements CommandExecutor.CommandExecuteListener {

        @Override
        public void onLine(String line) {

        }

        @Override
        public void onFinish(int exitCode) {

        }

        @Override
        public void onException(Throwable e) {

        }
    }
}
